<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>18. webpack相关问题 | Blog</title>
    <meta name="generator" content="VuePress 1.9.10">
    <link rel="icon" href="/blog/img/logo.png">
    <link rel="manifest" href="/blog/manifest.json">
    <link rel="apple-touch-icon" href="/blog/icons/apple-touch-icon-152x152.png">
    <link rel="mask-icon" href="/blog/icons/safari-pinned-tab.svg" color="#3eaf7c">
    <meta name="description" content="blog | js | node | vue | vuepress | webpack">
    <meta name="theme-color" content="#3eaf7c">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="msapplication-TileImage" content="/icons/msapplication-icon-144x144.png">
    <meta name="msapplication-TileColor" content="#000000">
    
    <link rel="preload" href="/blog/assets/css/0.styles.b6b82f87.css" as="style"><link rel="preload" href="/blog/assets/js/app.43c5da00.js" as="script"><link rel="preload" href="/blog/assets/js/2.d3a12b6d.js" as="script"><link rel="preload" href="/blog/assets/js/1.f8bb34da.js" as="script"><link rel="preload" href="/blog/assets/js/52.a56b61d7.js" as="script"><link rel="prefetch" href="/blog/assets/js/10.fde088a2.js"><link rel="prefetch" href="/blog/assets/js/11.c62b6b34.js"><link rel="prefetch" href="/blog/assets/js/12.27d4f152.js"><link rel="prefetch" href="/blog/assets/js/13.419d7748.js"><link rel="prefetch" href="/blog/assets/js/14.eb7a3d07.js"><link rel="prefetch" href="/blog/assets/js/15.114dfd5c.js"><link rel="prefetch" href="/blog/assets/js/16.85253907.js"><link rel="prefetch" href="/blog/assets/js/17.c2838453.js"><link rel="prefetch" href="/blog/assets/js/18.3256f17f.js"><link rel="prefetch" href="/blog/assets/js/19.d8afd0ae.js"><link rel="prefetch" href="/blog/assets/js/20.0d880388.js"><link rel="prefetch" href="/blog/assets/js/21.33b300c9.js"><link rel="prefetch" href="/blog/assets/js/22.4137860d.js"><link rel="prefetch" href="/blog/assets/js/23.b74cc977.js"><link rel="prefetch" href="/blog/assets/js/24.d99ad412.js"><link rel="prefetch" href="/blog/assets/js/25.ca9a652b.js"><link rel="prefetch" href="/blog/assets/js/26.66d6bac4.js"><link rel="prefetch" href="/blog/assets/js/27.95990a8e.js"><link rel="prefetch" href="/blog/assets/js/28.761c6ea4.js"><link rel="prefetch" href="/blog/assets/js/29.254ffe48.js"><link rel="prefetch" href="/blog/assets/js/3.af33e5d6.js"><link rel="prefetch" href="/blog/assets/js/30.6e4a155b.js"><link rel="prefetch" href="/blog/assets/js/31.665d02a7.js"><link rel="prefetch" href="/blog/assets/js/32.45b461b5.js"><link rel="prefetch" href="/blog/assets/js/33.17a0771a.js"><link rel="prefetch" href="/blog/assets/js/34.af9f8240.js"><link rel="prefetch" href="/blog/assets/js/35.e9dd53af.js"><link rel="prefetch" href="/blog/assets/js/36.e900b84a.js"><link rel="prefetch" href="/blog/assets/js/37.52783c0e.js"><link rel="prefetch" href="/blog/assets/js/38.5cb7cb7f.js"><link rel="prefetch" href="/blog/assets/js/39.0d72378d.js"><link rel="prefetch" href="/blog/assets/js/4.0a92875f.js"><link rel="prefetch" href="/blog/assets/js/40.dfcfa312.js"><link rel="prefetch" href="/blog/assets/js/41.3ae8c9d7.js"><link rel="prefetch" href="/blog/assets/js/42.bed07f3e.js"><link rel="prefetch" href="/blog/assets/js/43.170da95d.js"><link rel="prefetch" href="/blog/assets/js/44.eec82bc0.js"><link rel="prefetch" href="/blog/assets/js/45.b5a61f3a.js"><link rel="prefetch" href="/blog/assets/js/46.dbdb669f.js"><link rel="prefetch" href="/blog/assets/js/47.f3b25bee.js"><link rel="prefetch" href="/blog/assets/js/48.6c3ba867.js"><link rel="prefetch" href="/blog/assets/js/49.2c3070ea.js"><link rel="prefetch" href="/blog/assets/js/5.3b9be48d.js"><link rel="prefetch" href="/blog/assets/js/50.4a2a7438.js"><link rel="prefetch" href="/blog/assets/js/51.b3b493a3.js"><link rel="prefetch" href="/blog/assets/js/53.8f36ae1d.js"><link rel="prefetch" href="/blog/assets/js/54.8ee09618.js"><link rel="prefetch" href="/blog/assets/js/55.527c5d9c.js"><link rel="prefetch" href="/blog/assets/js/56.a09690f4.js"><link rel="prefetch" href="/blog/assets/js/57.cf4bc588.js"><link rel="prefetch" href="/blog/assets/js/58.0c8b9d19.js"><link rel="prefetch" href="/blog/assets/js/59.7d09c3f1.js"><link rel="prefetch" href="/blog/assets/js/6.7b96ebf4.js"><link rel="prefetch" href="/blog/assets/js/60.52e5c6db.js"><link rel="prefetch" href="/blog/assets/js/61.afa66052.js"><link rel="prefetch" href="/blog/assets/js/62.d7a75678.js"><link rel="prefetch" href="/blog/assets/js/63.77765300.js"><link rel="prefetch" href="/blog/assets/js/64.9777d386.js"><link rel="prefetch" href="/blog/assets/js/65.deeca199.js"><link rel="prefetch" href="/blog/assets/js/66.aba723e9.js"><link rel="prefetch" href="/blog/assets/js/67.47b5088b.js"><link rel="prefetch" href="/blog/assets/js/68.3178dffd.js"><link rel="prefetch" href="/blog/assets/js/69.a0f4810a.js"><link rel="prefetch" href="/blog/assets/js/7.7e58b9c4.js"><link rel="prefetch" href="/blog/assets/js/70.5b120c62.js"><link rel="prefetch" href="/blog/assets/js/71.2335838f.js"><link rel="prefetch" href="/blog/assets/js/vendors~docsearch.2493936b.js">
    <link rel="stylesheet" href="/blog/assets/css/0.styles.b6b82f87.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/blog/" class="home-link router-link-active"><!----> <span class="site-name">Blog</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/blog/" class="nav-link">
  home
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="long-ui" class="dropdown-title"><span class="title">long-ui</span> <span class="arrow down"></span></button> <button type="button" aria-label="long-ui" class="mobile-dropdown-title"><span class="title">long-ui</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/ui/" class="nav-link">
  UI简介
</a></li><li class="dropdown-item"><!----> <a href="https://weberlong.github.io/long-ui/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  预览
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://github.com/WeberLong/long-ui" target="_blank" rel="noopener noreferrer" class="nav-link external">
  源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><a href="/blog/archives/" class="nav-link">
  archives
</a></div><div class="nav-item"><a href="/blog/interview/" class="nav-link router-link-active">
  interview
</a></div> <a href="https://github.com/WeberLong" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/blog/" class="nav-link">
  home
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="long-ui" class="dropdown-title"><span class="title">long-ui</span> <span class="arrow down"></span></button> <button type="button" aria-label="long-ui" class="mobile-dropdown-title"><span class="title">long-ui</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/ui/" class="nav-link">
  UI简介
</a></li><li class="dropdown-item"><!----> <a href="https://weberlong.github.io/long-ui/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  预览
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://github.com/WeberLong/long-ui" target="_blank" rel="noopener noreferrer" class="nav-link external">
  源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><a href="/blog/archives/" class="nav-link">
  archives
</a></div><div class="nav-item"><a href="/blog/interview/" class="nav-link router-link-active">
  interview
</a></div> <a href="https://github.com/WeberLong" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><a href="/blog/interview/" aria-current="page" class="sidebar-link">面试题</a></li><li><section class="sidebar-group depth-0"><a href="/blog/interview/css/1/" class="sidebar-heading clickable"><span>css</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/interview/css/1.html" class="sidebar-link">1. 如何垂直居中一个元素？</a></li><li><a href="/blog/interview/css/2.html" class="sidebar-link">2. BFC</a></li><li><a href="/blog/interview/css/3.html" class="sidebar-link">3. 移动端1px问题的解决办法</a></li><li><a href="/blog/interview/css/4.html" class="sidebar-link">4. CSS清除浮动的几种方法</a></li><li><a href="/blog/interview/css/5.html" class="sidebar-link">5. opacity:0、visibility:hidden 和 display:none 三者区别？</a></li><li><a href="/blog/interview/css/6.html" class="sidebar-link">6. css绘制三角形五种方法？</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/blog/interview/js/1/" class="sidebar-heading clickable open"><span>js</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/interview/js/1.html" class="sidebar-link">1. 谈谈对this的理解</a></li><li><a href="/blog/interview/js/2.html" class="sidebar-link">2. new操作符具体干了什么呢？如何实现？</a></li><li><a href="/blog/interview/js/3.html" class="sidebar-link">3. 什么是原型链？</a></li><li><a href="/blog/interview/js/4.html" class="sidebar-link">4. 事件委托是什么？</a></li><li><a href="/blog/interview/js/5.html" class="sidebar-link">5. 重排与重绘的区别，什么情况下会触发？</a></li><li><a href="/blog/interview/js/6.html" class="sidebar-link">6. 去除数组重复成员的方法</a></li><li><a href="/blog/interview/js/7.html" class="sidebar-link">7. 深拷贝和浅拷贝的区别是什么？实现一个深拷贝</a></li><li><a href="/blog/interview/js/8.html" class="sidebar-link">8. 柯里化函数实现</a></li><li><a href="/blog/interview/js/9.html" class="sidebar-link">9. 什么是闭包？闭包的作用是什么？</a></li><li><a href="/blog/interview/js/10.html" class="sidebar-link">10. Promise的 all/any/race/allSettled 方法的区别</a></li><li><a href="/blog/interview/js/11.html" class="sidebar-link">11. jsonp的原理是什么？</a></li><li><a href="/blog/interview/js/12.html" class="sidebar-link">12. 介绍一下js的节流与防抖?</a></li><li><a href="/blog/interview/js/13.html" class="sidebar-link">13. js的事件循环是什么？</a></li><li><a href="/blog/interview/js/14.html" class="sidebar-link">14. 手写call、apply及bind函数</a></li><li><a href="/blog/interview/js/15.html" class="sidebar-link">15. ['1', '2', '3'].map(parseInt)执行结果，what &amp; why ?</a></li><li><a href="/blog/interview/js/16.html" class="sidebar-link">16. 手写一个Promise</a></li><li><a href="/blog/interview/js/17.html" class="sidebar-link">17. js数组扁平化的六种方式</a></li><li><a href="/blog/interview/js/18.html" aria-current="page" class="active sidebar-link">18. webpack相关问题</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/blog/interview/js/18.html#_1-介绍下-webpack-热更新原理" class="sidebar-link">1. 介绍下 webpack 热更新原理</a></li><li class="sidebar-sub-header"><a href="/blog/interview/js/18.html#_2-babel-怎么把字符串解析成-ast-是怎么进行词法-语法分析的" class="sidebar-link">2. babel 怎么把字符串解析成 AST，是怎么进行词法/语法分析的？</a></li><li class="sidebar-sub-header"><a href="/blog/interview/js/18.html#_3-介绍下-npm-模块安装机制-为什么输入-npm-install-就可以自动安装对应的模块" class="sidebar-link">3. 介绍下 npm 模块安装机制，为什么输入 npm install 就可以自动安装对应的模块？</a></li><li class="sidebar-sub-header"><a href="/blog/interview/js/18.html#_4-webpack插件开发" class="sidebar-link">4. webpack插件开发？</a></li></ul></li><li><a href="/blog/interview/js/19.html" class="sidebar-link">19. http和https的区别</a></li><li><a href="/blog/interview/js/20.html" class="sidebar-link">20. 实现 instanceOf</a></li><li><a href="/blog/interview/js/21.html" class="sidebar-link">21. 打印出1-10000之间的所有对称数</a></li><li><a href="/blog/interview/js/22.html" class="sidebar-link">22. for of, for in和forEach, map的区别？</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/blog/interview/frame/1/" class="sidebar-heading clickable"><span>框架</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/interview/frame/1.html" class="sidebar-link">1. Vue基础</a></li><li><a href="/blog/interview/frame/2.html" class="sidebar-link">2. 30道vue面试题</a></li></ul></section></li><li><section class="sidebar-group depth-0"><a href="/blog/interview/leetcode/1/" class="sidebar-heading clickable"><span>算法</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/interview/leetcode/1.html" class="sidebar-link">1. JS面试中常见的算法题</a></li><li><a href="/blog/interview/leetcode/2.html" class="sidebar-link">2. 说说你对二分查找的理解？如何实现？</a></li><li><a href="/blog/interview/leetcode/3.html" class="sidebar-link">3. 介绍下深度优先遍历和广度优先遍历，如何实现？</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="_18-webpack相关问题"><a href="#_18-webpack相关问题" class="header-anchor">#</a> 18. webpack相关问题</h1> <h2 id="_1-介绍下-webpack-热更新原理"><a href="#_1-介绍下-webpack-热更新原理" class="header-anchor">#</a> 1. 介绍下 webpack 热更新原理</h2> <ol><li>当修改了一个或多个文件；</li> <li>文件系统接收更改并通知webpack；</li> <li>webpack重新编译构建一个或多个模块，并通知HMR服务器进行更新；</li> <li>HMR Server 使用webSocket通知HMR runtime 需要更新，HMR运行时通过HTTP请求更新jsonp；</li> <li>HMR运行时替换更新中的模块，如果确定这些模块无法更新，则触发整个页面刷新。</li></ol> <h2 id="_2-babel-怎么把字符串解析成-ast-是怎么进行词法-语法分析的"><a href="#_2-babel-怎么把字符串解析成-ast-是怎么进行词法-语法分析的" class="header-anchor">#</a> 2. babel 怎么把字符串解析成 AST，是怎么进行词法/语法分析的？</h2> <blockquote><p>Babel 是将 ES6、ES7等代码转译为 ES5 代码且能安全稳定运行的工具。<br>
1.先对输入代码进行分词，根据最小有效语法单元，对字符串进行切割。 -&gt; 2.AST，然后进行语法分析，会涉及到读取、暂存、回溯、暂存点销毁等操作。 -&gt; 3.然后转换生成新的 AST。-&gt; 4.最后根据新生成的 AST 输出目标代码。</p></blockquote> <p><strong>解析</strong></p> <ul><li>Babylon是一个解析器，它可以将javascript字符串，转化为更加友好的表现形式，称之为抽象语法树；</li> <li>在解析过程中有两个阶段：词法分析和语法分析，</li> <li>词法分析阶段：字符串形式的代码转换为令牌（tokens）流,令牌类似于AST中的节点；</li> <li>语法分析阶段：把一个令牌流转化为AST的形式，同时这个阶段会把令牌中的信息转化为AST的表述结构</li></ul> <p><strong>转换</strong></p> <ul><li>babel-traverse 模块允许你浏览、分析和修改抽象语法树（AST Abstract Syntax Tree）</li> <li>Babel接收解析得到的AST并通过babel-traverse对其进行深度优先遍历，在此过程中对节点进行添加、更新及移除操作。</li></ul> <p><strong>生成</strong></p> <ul><li>babel-generator 模块用来将转换后的抽象语法树（AST Abstract Syntax Tree）转化为Javascript 字符串</li> <li>将经过转换的AST通过babel-generator再转换为js代码，过程及时深度遍历整个AST,然后构建转换后的代码字符串。</li></ul> <h2 id="_3-介绍下-npm-模块安装机制-为什么输入-npm-install-就可以自动安装对应的模块"><a href="#_3-介绍下-npm-模块安装机制-为什么输入-npm-install-就可以自动安装对应的模块" class="header-anchor">#</a> 3. 介绍下 npm 模块安装机制，为什么输入 npm install 就可以自动安装对应的模块？</h2> <ol><li>发出npm install命令；</li> <li>npm 向 registry 查询模块压缩包的网址；</li> <li>下载压缩包，存放在~/.npm目录；</li> <li>解压压缩包到当前项目的node_modules目录；</li></ol> <h2 id="_4-webpack插件开发"><a href="#_4-webpack插件开发" class="header-anchor">#</a> 4. webpack插件开发？</h2> <p><strong>webpack 插件由以下组成:</strong></p> <ul><li>一个 JavaScript 命名函数或 JavaScript 类。</li> <li>在插件函数的 prototype 上定义一个 apply 方法。</li> <li>指定一个绑定到 webpack 自身的事件钩子。</li> <li>处理 webpack 内部实例的特定数据。</li> <li>功能完成后调用 webpack 提供的回调。</li></ul> <p>Compiler 它扩展自 Tapable 类，设置了一系列事件钩子和各种配置参数，并定义了 webpack 诸如启动编译、观测文件变动、将编译结果文件写入本地等一系列核心方法。</p> <p><strong>常见事件钩子介绍：</strong></p> <ul><li>beforeRun：在编译器开始读取 records 之前执行;</li> <li>run：在读取 records 之前;</li> <li>thisCompilation：在 compilation 初始化时执行;</li> <li>compilation：在 compilation 创建之后执行;</li> <li>make：在 complication 完成之前执行;</li> <li>afterCompilation：在 compilation 完成后执行;</li> <li>emit：在生成文件到 output 目录之前执行;</li> <li>afterEmit：在生成文件到 output 目录之后执行;</li> <li>done：在 compilation 完成之后执行;</li></ul> <p><strong>实现方法：</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">MyWebpackPlugin</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">doneCallback<span class="token punctuation">,</span> emitCallback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>emitCallback <span class="token operator">=</span> emitCallback
    <span class="token keyword">this</span><span class="token punctuation">.</span>doneCallback <span class="token operator">=</span> doneCallback
  <span class="token punctuation">}</span>
  <span class="token function">apply</span><span class="token punctuation">(</span><span class="token parameter">compiler</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    compiler<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>emit<span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token string">'MyWebpackPlugin'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 在 emit 事件中回调 emitCallback</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emitCallback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    compiler<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>done<span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token string">'MyWebpackPlugin'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 在 done 事件中回调 doneCallback</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">doneCallback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    compiler<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>compilation<span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token string">'MyWebpackPlugin'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// compilation（'编译器'对'编译ing'这个事件的监听）</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;The compiler is starting a new compilation...&quot;</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    compiler<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>compile<span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token string">'MyWebpackPlugin'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// compile（'编译器'对'开始编译'这个事件的监听）</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;The compiler is starting to compile...&quot;</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// 导出插件</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> MyWebpackPlugin<span class="token punctuation">;</span>


<span class="token comment">// 使用插件</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token keyword">new</span> <span class="token class-name">MyWebpackPlugin</span><span class="token punctuation">(</span>
      <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token comment">// Webpack 模块完成转换成功</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'emit 事件发生啦，所有模块的转换和代码块对应的文件已经生成好~'</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token comment">// Webpack 构建成功，并且文件输出了后会执行到这里，在这里可以做发布文件操作</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'done 事件发生啦，成功构建完成~'</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</code></pre></div></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/blog/interview/js/17.html" class="prev">
        17. js数组扁平化的六种方式
      </a></span> <span class="next"><a href="/blog/interview/js/19.html">
        19. http和https的区别
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/blog/assets/js/app.43c5da00.js" defer></script><script src="/blog/assets/js/2.d3a12b6d.js" defer></script><script src="/blog/assets/js/1.f8bb34da.js" defer></script><script src="/blog/assets/js/52.a56b61d7.js" defer></script>
  </body>
</html>
